import logging
from flask import Blueprint,current_app, jsonify
from flask import g
from flask import json
from flask import redirect
from flask import request
from api_v1.my_decorators import is_login
from models import Area, House, Facility, User, Order
from manager import redis_store, db
from response_code import RET, ret_map
from utils.qiniu_sdk import put_qiniu

house_blueprint = Blueprint('house', __name__,url_prefix="/api/v1/house")

#封装获取地区数据的方法
def get_area():
    try:
        #访问数据库获取分类数据
        area_list = Area.query.all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(code=RET.DATAERR,msg='获取数据失败')
    #遍历数据库的输入转成字典存入列表
    alist=[i.to_dict() for i in area_list]
    return alist

#封装获取设施数据的方法
def get_facility():
    try:
        #访问数据库获取设施数据
        facility_list = Facility.query.all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(code=RET.DATAERR,msg='获取数据失败')
    #遍历数据库的输入转成字典存入列表
    facility=[i.to_dict() for i in facility_list]
    return facility

#搜索功能
@house_blueprint.route("/search")
@is_login
def search():
    # 1.获取参数
    areaId = request.args.get("aid")
    startDate = request.args.get("sd")
    endDate = request.args.get("ed")
    sortKey = request.args.get("sk")
    action = request.args.get("area")
    # 2.校验参数
    # 2.1 为空校验
    if not all([areaId]):
        return jsonify(code=RET.PARAMERR,msg="参数不全")
    # 2.校验日期
    if startDate > endDate:
        return jsonify(code=RET.DATAERR,msg="日期错误")
    # # 2.2操作类型校验
    # if  action == "renew":
    #     return redirect("/api/v1/house/search")

    user = g.user
    con = [House.area_id==areaId]
    if user:
        con.append(House.user_id!=user.id)
    hlist = House.query.filter(*con)

    sort = House.create_time.desc()
    if sortKey == "booking":
        sort = House.order_count.desc()
    elif sortKey == "price-inc":
        sort = House.price.asc()
    elif sortKey == "price-des":
        sort = House.price.desc()

    hlist = hlist.order_by(sort)

    # if not g.user:
    #     # 3.1 查询最新房源
    #     if sortKey == "new":
    #         try:
    #             houses = House.query.filter(House.area_id==areaId).order_by(House.create_time.desc()).all()
    #         except Exception as e:
    #             current_app.logger.error(e)
    #             return jsonify(code=RET.DBERR,msg="数据库查询错误")
    #     # 3.2查询最热房源
    #     if sortKey == "booking":
    #         try:
    #             houses = House.query.filter(House.area_id==areaId).order_by(House.order_count.desc()).all()
    #         except Exception as e:
    #             current_app.logger.error(e)
    #             return jsonify(code=RET.DBERR,msg="数据库查询错误")
    #     # 3.2按价格从高到低查询房源
    #     if sortKey == "price-inc":
    #         try:
    #             houses = House.query.filter(House.area_id==areaId).order_by(House.price).all()
    #         except Exception as e:
    #             current_app.logger.error(e)
    #             return jsonify(code=RET.DBERR,msg="数据库查询错误")
    #     # 3.2按价格从低到高查询房源
    #     if sortKey == "price-des":
    #         try:
    #             houses = House.query.filter(House.area_id==areaId).order_by(House.price.desc()).all()
    #         except Exception as e:
    #             current_app.logger.error(e)
    #             return jsonify(code=RET.DBERR, msg="数据库查询错误")
    # else:
    #     condition = [House.area_id == areaId,House.user_id!=g.user.id]
    #     # if startDate-endDate
    #
    #     if sortKey == "new":
    #         try:
    #             houses = House.query.filter(*condition).order_by(House.create_time.desc()).all()
    #         except Exception as e:
    #             current_app.logger.error(e)
    #             return jsonify(code=RET.DBERR, msg="数据库查询错误")
    #             # 3.2查询最热房源
    #     if sortKey == "booking":
    #         try:
    #             houses = House.query.filter(*condition).order_by(House.order_count.desc()).all()
    #         except Exception as e:
    #             current_app.logger.error(e)
    #             return jsonify(code=RET.DBERR, msg="数据库查询错误")
    #             # 3.2按价格从高到低查询房源
    #     if sortKey == "price-inc":
    #         try:
    #             houses = House.query.filter(*condition).order_by(House.price).all()
    #         except Exception as e:
    #             current_app.logger.error(e)
    #             return jsonify(code=RET.DBERR, msg="数据库查询错误")
    #             # 3.2按价格从低到高查询房源
    #     if sortKey == "price-des":
    #         try:
    #             houses = House.query.filter(*condition).order_by(House.price.desc()).all()
    #         except Exception as e:
    #             current_app.logger.error(e)
    #             return jsonify(code=RET.DBERR, msg="数据库查询错误")
    # hlist = []
    # for house in houses:
    #     hlist.append(house.to_dict())

    order_list = Order.query.filter(Order.begin_date<startDate, Order.end_date>endDate)
    order_list1 = Order.query.filter(Order.begin_date>=startDate, Order.begin_date<=endDate)
    order_list2 = Order.query.filter(Order.end_date<=endDate, Order.end_date>=startDate)

    house_id = [i.house.id for i in order_list]

    for i in order_list1:
        house_id.append(i.house.id)

    for i in order_list2:
        house_id.append(i.house.id)

    hlist = hlist.filter(House.id.notin_(house_id)).all()
    hlist1 = []
    for house in hlist:
        hlist1.append(house.to_dict())

    # 4. 查询城区信息
    try:
        areas = Area.query.all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(code=RET.DBERR, msg="数据库查询错误")
    alist = []
    for area in areas:
        alist.append(area.to_dict())

    return jsonify(code=RET.OK, hlist=hlist1, alist=alist)

#房屋详情页展示
@house_blueprint.route("/<int:id>")
def detail(id):
    try:
        house = House.query.get(id)
    except Exception as e:
        return jsonify(code=RET.DBERR, msg="数据库查询失败")
    facility_list = []
    for facility in house.facilities:
        facility_list.append(facility.to_dict())
    return jsonify(code=RET.OK, house=house.to_full_dict(), facility_list=facility_list, booking=1)

# 首页展示
@house_blueprint.route('/index', methods=["GET"])
@is_login
def house_index():
    alist = get_area()

    hlist = House.query.order_by(House.create_time.desc()).limit(5).all()
    hlist2 = [house.to_dict() for house in hlist]

    # 判断是否登陆
    if not g.user:
        return jsonify(code=RET.LOGINERR, alist=alist, hlist=hlist2)

    # 返回响应
    return jsonify(code=RET.OK, alist=alist, name=g.user.name, hlist=hlist2)


# 我的房源
@house_blueprint.route('/',methods=["GET","POST"])
@is_login
def my_house():
    if request.method == "GET":
        # 1,判断是否当前用户登录
        if not g.user:
            return jsonify(code=RET.USERERR, msg="当前用户异常")
        try:
            # 2,1查询数据库中用户数据
            user = User.query.filter(User.id_card == g.user.id_card).first()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(code=RET.DBERR, msg="用户查询失败")
        # 2,2判断用户是否存在
        if not user:
            return jsonify(code=RET.DATAERR, msg="用户不存在")
        # 2,3判断用户是否已经实名认证
        if not user.id_card:
            return jsonify(code=RET.USERERR, msg="用户未实名认证")

        houses = None
        try:
            # 2,4查询数据库中当前用户的房源
            houses = House.query.filter(House.user_id == g.user.id).order_by(House.create_time.desc()).all()
        except Exception as e:
            logging.error("查询数据库-------失败")
        # 2,5判断当前用户是否有房源
        if houses:
            houses_list = []
            for house in houses:
                houses_list.append(house.to_dict())
            return jsonify(code=RET.OK, msg="用户已认证", hlist=houses_list)
        else:
            return jsonify(code=RET.OK, msg="用户已认证")
    # 1,获取参数
    title = request.form.get("title")  # 标题
    price = request.form.get("price")  # 价格
    area = request.form.get("area_id")  # 区域
    address = request.form.get("address")  # 详细地址
    room_count = request.form.get("room_count")  # 房间数
    acreage = request.form.get("acreage")  # 房屋面积
    unit = request.form.get("unit")  # 房屋单元， 如几室几厅
    capacity = request.form.get("capacity")  # 房屋容纳的人数
    beds = request.form.get("beds")  # 房屋床铺的配置
    deposit = request.form.get("deposit")  # 房屋押金
    min_days = request.form.get("min_days")  # 最少入住天数
    max_days = request.form.get("max_days")  # 最多入住天数，0表示不限制
    # 获取设备设施列表
    facility_id = request.form.getlist("facility")  # 房屋的设施
    # 3,校验参数
    # 3,1为空校验
    if not all([title, price, address, room_count, acreage, unit, capacity, beds, deposit, min_days, max_days]):
        return jsonify(code=RET.PARAMERR, msg="参数不全")
    try:
        price = int(price)
        deposit = int(deposit)
        room_count = int(room_count)
        acreage = int(acreage)
        capacity = int(capacity)
        min_days = int(min_days)
        max_days = int(max_days)
    except Exception as e:
        current_app.logger.error(e)
        logging.error("数据类型错误")
        return jsonify(code=RET.PARAMERR, msg="数据类型错误")
    # 用户输入数据进行判断
    if price < 0:
        return jsonify(code=RET.PARAMERR, msg=ret_map[RET.PARAMERR])
    elif deposit < 0:
        return jsonify(code=RET.PARAMERR, msg=ret_map[RET.PARAMERR])
    elif room_count < 0:
        return jsonify(code=RET.PARAMERR, msg=ret_map[RET.PARAMERR])
    elif acreage <= 0:
        return jsonify(code=RET.PARAMERR, msg=ret_map[RET.PARAMERR])
    elif capacity <= 0:
        return jsonify(code=RET.PARAMERR, msg=ret_map[RET.PARAMERR])
    elif min_days <= 0:
        return jsonify(code=RET.PARAMERR, msg=ret_map[RET.PARAMERR])
    elif max_days < 0:
        return jsonify(code=RET.PARAMERR, msg=ret_map[RET.PARAMERR])
    # 创建房屋对象,并添加数据
    house = House()
    house.user_id = g.user.id
    house.title = title
    house.price = price
    house.address = address
    house.room_count = room_count
    house.acreage = acreage
    house.unit = unit
    house.capacity = capacity
    house.beds = beds
    house.deposit = deposit
    house.min_days = min_days
    house.max_days = max_days
    house.area_id = area
    # facilities = None
    try:
        # 查询数据库中的设施
        facilities = Facility.query.filter(Facility.id.in_(facility_id)).all()
    except Exception as e:
        # current_app.logger.error(e)
        logging.error("查询设施有误")
    # 3,2判断设施是否存在
    if not facilities:
        return jsonify(code=RET.DATAERR, msg="设施不存在")
    # 将设施对象添加到房屋中的字段
    house.facilities = facilities
    try:
        # 数据添加并提交到数据库中
        house.add_update()
    except Exception as e:
        # current_app.logger.error(e)
        logging.error("入库失败")
        return jsonify(code=RET.DBERR, msg="数据入库失败")
    # 返回成功响应
    return jsonify(code=RET.OK, msg="数据入库成功", house_id=house.id)

# 获取房源发布页面
@house_blueprint.route('/area_facility')
def area_facility():
    alist = get_area()
    facility_list = get_facility()
    # try:
    #     areas = Area.query.all()
    #     facilities = Facility.query.all()
    #
    # except Exception as e:
    #     logging.error("查询城区区域失败")
    #
    # if not all([areas, facilities]):
    #     return jsonify(code=RET.DATAERR, msg="城区区域不存在")
    #
    # area_list = []
    # for area in areas:
    #     area_list.append(area.to_dict())
    #
    # # 列表推导式
    # facility_list = [facility.to_dict() for facility in facilities]
    return jsonify(code=RET.OK, area=alist, facility=facility_list)

#获取房屋图片
#房屋图片接口
# 发布新房源
# @house_blueprint.route('/', methods=['POST'])
# @is_login
# def send_new_house():
#
# 发布图片
@house_blueprint.route('/image', methods=['POST'])
@is_login
def house_image():
    # 1,获取参数
    house_id = request.form.get('house_id')
    avatar = request.files.get("house_image")
    # 2,校验参数
    if not avatar:
        return jsonify(code=RET.DATAERR, msg="图片不存在")
    try:
        # 2,1调用七牛云的方法
        image_url = put_qiniu(avatar)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(code=RET.THIRDERR, msg="七牛云异常")
    # 2,2判断图片是否存在
    if not image_url:
        return jsonify(code=RET.DATAERR, msg="图片不存在")
    try:
        house = House.query.filter(House.id == house_id).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(code=RET.DBERR, msg="当前房源查询失败")
    # 2,3判断当前用户是否有房源信息
    if not house:
        return jsonify(code=RET.DATAERR, msg="当前无房源信息")
    # 2,4将图片名字添加到房屋对象
    house.index_image_url = image_url
    try:
        # house.add_update()
        db.session.add(house)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
    # 2,5获取图片资源
    image = "http://pr4eo8v5p.bkt.clouddn.com/" + image_url
    # 3,返回响应，并传递图片资源
    return jsonify(code=RET.OK, msg="图片上传成功", url=image)